#ifndef LOADMQO_H_
#define LOADMQO_H_

#include <iostream>
#include <fstream>
#include <string>
#include <GL/gl.h>
#include <GL/glu.h>
#include "MqoObject.h"

#define MAX_MQO_SIZE 65536
#define SIZE_STR 256

using namespace std;

class MqoLoader {
public:
	MqoLoader();
	virtual ~MqoLoader();
	/*
	 * mqoInput関数
	 * @param FILE* mqoファイルのポインタ
	 * @param MqoObject mqoのオブジェクト
	 */
	static void mqoInput(FILE *fp, MqoObject *mqo) {
		char buf[MAX_MQO_SIZE];

		while (!feof(fp)) {
			fgets(buf, SIZE_STR, fp);
			// vertex読み込み
			if (strstr(buf, "vertex")) {
				//vertex size読み込み
				sscanf(buf, " vertex %d", &mqo->vertex_size);
				//vertex size分の配列を確保
				for (int i = 0; i < mqo->vertex_size; i++) {
					mqo->vertex = (GLfloat3d *) malloc(sizeof(GLfloat3d));
				}
				mqoReadVertex(fp, mqo->vertex);
			}

			// face読み込み
			if (strstr(buf, "face ")) {
				sscanf(buf, " face %d", &mqo->face_size);
				mqo->face = (mqo_face *) calloc(mqo->face_size,
						sizeof(mqo_face));
				mqoReadFace(fp, mqo->face);
			}
		}
	}

private:

	static void mqoReadVertex(FILE *fp, GLfloat3d *v) {
		char buf[SIZE_STR];
		int i = 0;

		while (1) {
			fgets(buf, SIZE_STR,fp);
			if (strstr(buf, "}"))
				break;
			sscanf(buf, "%f %f %f", &v[i].x, &v[i].y, &v[i].z);
			i++;
		}
	}

	static void mqoReadFace(FILE *fp, mqo_face f[]) {
		char buf[SIZE_STR];
		char *pStr;
		int i = 0;

		while (1) {
			fgets(buf, SIZE_STR,fp);
			if (strstr(buf, "}"))
				break;

			// 面を構成する頂点数
			sscanf(buf, "%d", &f[i].n);

			// 頂点(V)の読み込み
			if ((pStr = strstr(buf, "V(")) != NULL) {
				switch (f[i].n) {
				case 3:
					sscanf(pStr, "V(%d %d %d)", &f[i].v[0], &f[i].v[1],
							&f[i].v[2]);
					break;
				case 4:
					sscanf(pStr, "V(%d %d %d %d)", &f[i].v[0], &f[i].v[1],
							&f[i].v[2], &f[i].v[3]);
					break;
				default:
					break;
				}
			}

			// マテリアル(M)の読み込み
			f[i].m = 0;
			if ((pStr = strstr(buf, "M(")) != NULL) {
				sscanf(pStr, "M(%d)", &f[i].m);
			}

			// UVマップ(UV)の読み込み
			if ((pStr = strstr(buf, "UV(")) != NULL) {
				switch (f[i].n) {
				case 3: // 頂点数3
					sscanf(pStr, "UV(%f %f %f %f %f %f)", &f[i].uv[0].x,
							&f[i].uv[0].y, &f[i].uv[1].x, &f[i].uv[1].y,
							&f[i].uv[2].x, &f[i].uv[2].y);
					break;

				case 4: // 頂点数4
					sscanf(pStr, "UV(%f %f %f %f %f %f %f %f)", &f[i].uv[0].x,
							&f[i].uv[0].y, &f[i].uv[1].x, &f[i].uv[1].y,
							&f[i].uv[2].x, &f[i].uv[2].y, &f[i].uv[3].x,
							&f[i].uv[3].y);
					break;
				default:
					break;
				}
			}

			i++;
		}

	}
};

#endif /*LOADMQO_H_*/
